﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;
using Pixysoft.Framework.Reflection;
using System.Xml.Serialization;
using Pixysoft.TestDrivens;
using Pixysoft.Framework.Configurations.Core;
using Pixysoft.Tools;
using Pixysoft.Framework.Verifications;
using System.Threading;

namespace Pixysoft.Framework.Configurations.Controller
{
    /// <summary>
    /// 不支持值类型的array、所有的范型集合、值类型
    /// </summary>
    static partial class DynamicReflectionController
    {
        public static object Deserialize(Type objectType, IXmlNode value)
        {
            DotNetPropertyType propertyType = Pixysoft.Tools.ParserHelper.GetPropertyType(objectType);

            switch (propertyType)
            {
                case DotNetPropertyType.Binary:
                    {
                        if (string.IsNullOrEmpty(value.Text))
                            return null;

                        return Pixysoft.Security.UrlCoder.UrlDecodeToBytes(value.Text);
                    }


                case DotNetPropertyType.Object:
                case DotNetPropertyType.Interface:
                    {
                        break;
                    }

                case DotNetPropertyType.BinaryList:
                case DotNetPropertyType.EnumList:
                case DotNetPropertyType.InterfaceList:
                case DotNetPropertyType.ObjectList:
                case DotNetPropertyType.ValueList:
                    {
                        Type listObjectType = objectType.GetGenericArguments()[0];

                        IList listObjectValue = Activator.CreateInstance(objectType) as IList;

                        //2010-08-30 使用反射和动态性能一样 选择方便的

                        //IList listObjectValue = ReflectionManager.CreateDynamicType(objectType).GetDefaultConstructor().Invoke() as IList;

                        foreach (IXmlNode subvalue in value.Nodes)
                        {
                            listObjectValue.Add(Deserialize(listObjectType, subvalue));
                        }

                        return listObjectValue;
                    }

                case DotNetPropertyType.EnumArray:
                case DotNetPropertyType.ValueArray:
                case DotNetPropertyType.InterfaceArray:
                case DotNetPropertyType.ObjectArray:
                    {
                        Type arrayObjectType = objectType.GetElementType();

                        Array arrayObjectValue = Array.CreateInstance(arrayObjectType, value.Nodes.Count);

                        //2010-08-30 使用反射 比 动态： 103ms :: 276ms

                        //Array arrayObjectValue = ReflectionManager.CreateDynamicType(objectType)
                        //    .GetConstructor(new Type[] { typeof(int) }).Invoke(new object[] { value.Nodes.Count }) as Array;

                        int counter = 0;

                        foreach (IXmlNode subvalue in value.Nodes)
                        {
                            arrayObjectValue.SetValue(Deserialize(arrayObjectType, subvalue), counter++);
                        }

                        return arrayObjectValue;
                    }

                case DotNetPropertyType.Enum:
                case DotNetPropertyType.Value:
                    {
                        if (string.IsNullOrEmpty(value.Text))
                            return Pixysoft.Tools.ParserHelper.GetNullValue(objectType);


                        object objectvalue = null;

                        if (!Pixysoft.Tools.ParserHelper.TryParse(objectType, value.Text, out objectvalue, null))
                            throw new Exception("unknown object value. " + value.Text);

                        return objectvalue;
                    }

                case DotNetPropertyType.Unknown:
                default:
                    throw new Exception("unknown object type.");
            }

            object objectValue = null;

            if (objectType.IsInterface)
                objectValue = ReflectionManager.CreatePojo(objectType);
            else
                objectValue = ReflectionManager.CreateDynamicType(objectType).GetDefaultConstructor().Invoke();

            if (objectValue == null)
                return null;

            IBeanMap objectBean = ReflectionManager.CreateBeanMap(objectValue);

            //主动取值策略

            IDummyType structureType = ReflectionManager.CreateDummyType(objectType);

            DynamicInterfacePropertyCollection iPropertyCollection = new DynamicInterfacePropertyCollection(structureType.GetInterfaces());

            foreach (IDummyPropertyInfo propertyinfo in propertyType == DotNetPropertyType.Interface ?
                CombineWithInterfaceProperties(structureType) : structureType.GetProperties())
            {
                PropertyInfo info = GetPropertyCombineWithInterface(objectType, propertyinfo.Name);

                DynamicPropertyStructure property = new DynamicPropertyStructure(info);

                property.InitializeProperty(iPropertyCollection, propertyinfo);

                if (property.IsIgnore)
                    continue;

                if (property.IsAttribute)
                {
                    GetPropertyValueByPropertyAttribute(objectBean, property, value);
                }
                else
                {
                    GetPropertyValue(objectBean, property, value);
                }
            }

            return objectBean.GetBean();
        }

        private static void GetPropertyValue(IBeanMap objectBean, DynamicPropertyStructure propertyStructure, IXmlNode value)
        {
            if (!propertyStructure.PropertyInfo.CanWrite)
                return;

            if (propertyStructure.PropertyType == null)
                throw new Exception(string.Format("missing property type in property structure. type:{0},property:{1}",
                    propertyStructure.ReflectPropertyInfo.DeclaringType.Name, propertyStructure.PropertyInfo.Name));


            switch (propertyStructure.PropertyType.PropertyType)
            {
                case DotNetPropertyType.Enum:
                case DotNetPropertyType.Value:
                case DotNetPropertyType.Object:
                case DotNetPropertyType.Binary:
                case DotNetPropertyType.Interface:
                    {
                        if (!value.Nodes.Contains(propertyStructure.PropertyName))
                        {
                            return;
                        }

                        IXmlNode childNode = value.Node[propertyStructure.PropertyName];

                        object childValue = Deserialize(propertyStructure.ReflectPropertyInfo.PropertyType, childNode);

                        objectBean.SetValue(propertyStructure.PropertyInfo.Name, childValue);

                        break;
                    }
                case DotNetPropertyType.EnumList:
                case DotNetPropertyType.ValueList:
                case DotNetPropertyType.EnumArray:
                case DotNetPropertyType.ValueArray:
                case DotNetPropertyType.ObjectList:
                case DotNetPropertyType.BinaryList:
                case DotNetPropertyType.ObjectArray:
                case DotNetPropertyType.InterfaceList:
                case DotNetPropertyType.InterfaceArray:
                    {
                        string propertyName = string.Format(default_format_element_arrayof, propertyStructure.PropertyName);

                        if (!value.Nodes.Contains(propertyName))
                        {
                            return;
                        }

                        IXmlNode childNode = value.Node[propertyName];

                        object childValue = Deserialize(propertyStructure.ReflectPropertyInfo.PropertyType, childNode);

                        objectBean.SetValue(propertyStructure.PropertyInfo.Name, childValue);

                        break;
                    }
                case DotNetPropertyType.Unknown:
                default:
                    {
                        //目前不支持集合里面是集合，例如List<byte[]>

                        break;
                    }
            }
        }

        private static void GetPropertyValueByPropertyAttribute(IBeanMap objectBean, DynamicPropertyStructure propertyStructure, IXmlNode value)
        {
            //应该用原property判断 不应该用接口判断

            if (!propertyStructure.PropertyInfo.CanWrite)
                return;

            if (propertyStructure.PropertyType == null)
                throw new Exception(string.Format("missing property type in property structure. type:{0},property:{1}",
                    propertyStructure.PropertyInfo.DeclaringType.Name, propertyStructure.PropertyInfo.Name));



            switch (propertyStructure.PropertyInfo.PropertyType.PropertyType)
            {
                case DotNetPropertyType.Enum:
                case DotNetPropertyType.Value:
                    {
                        string propertyValue = value.Properties[propertyStructure.PropertyName];

                        if (string.IsNullOrEmpty(propertyValue))
                            return;

                        object outPropertyValue = null;

                        if (!Pixysoft.Tools.ParserHelper.TryParse(
                            propertyStructure.PropertyInfo.PropertyType.DataType, propertyValue, out outPropertyValue, null))
                            return;

                        objectBean.SetValue(propertyStructure.PropertyInfo.Name, outPropertyValue);

                        break;
                    }
                case DotNetPropertyType.Object:
                case DotNetPropertyType.Interface:
                case DotNetPropertyType.Binary:
                case DotNetPropertyType.EnumArray:
                case DotNetPropertyType.ValueArray:
                case DotNetPropertyType.ObjectArray:
                case DotNetPropertyType.InterfaceArray:
                case DotNetPropertyType.BinaryList:
                case DotNetPropertyType.EnumList:
                case DotNetPropertyType.ValueList:
                case DotNetPropertyType.ObjectList:
                case DotNetPropertyType.InterfaceList:
                case DotNetPropertyType.Unknown:
                default:
                    {
                        throw new Exception(
                            string.Format("xml property mark do not support non-value type. propertyname={0}",
                            propertyStructure.PropertyName));
                    }
            }
        }



        /// <summary>
        /// 根据dummyType序列化为xmlNode
        /// 如果值不存在 返回null
        /// </summary>
        /// <param name="dummyType"></param>
        /// <returns></returns>
        public static XmlNode Serialize(object value)
        {
            if (value == null)
                return null;

            Type objectType = value.GetType();

            IDummyType dummyType = ReflectionManager.CreateDummyType(objectType);//如果使用延迟加载 性能更差

            XmlNode root = null;

            DotNetPropertyType propertyType = Pixysoft.Tools.ParserHelper.GetPropertyType(objectType);

            switch (propertyType)
            {
                case DotNetPropertyType.BinaryList:
                case DotNetPropertyType.EnumList:
                case DotNetPropertyType.InterfaceList:
                case DotNetPropertyType.ObjectList:
                case DotNetPropertyType.ValueList:
                    {
                        // 全无 746ms

                        IDummyType arrayObjectType = dummyType.GetGenericArguments()[0];

                        // 786ms

                        root = new XmlNode(string.Format(default_format_element_arrayof, arrayObjectType.Name));

                        IList valueList = value as IList;

                        foreach (object subValue in valueList)
                        {
                            //825ms

                            IXmlNode subNode = Serialize(subValue);

                            if (subNode != null)
                                root.Nodes.Add(subNode);

                            //1,881ms
                        }

                        return root;
                    }

                case DotNetPropertyType.EnumArray:
                case DotNetPropertyType.ValueArray:
                case DotNetPropertyType.InterfaceArray:
                case DotNetPropertyType.ObjectArray:
                    {
                        // 全无 746ms

                        IDummyType arrayObjectType = dummyType.GetElementType();

                        // 786ms

                        root = new XmlNode(string.Format(default_format_element_arrayof, arrayObjectType.Name));

                        IList valueList = value as IList;

                        foreach (object subValue in valueList)
                        {
                            //825ms

                            IXmlNode subNode = Serialize(subValue);

                            if (subNode != null)
                                root.Nodes.Add(subNode);

                            //1,348ms
                        }

                        return root;
                    }

                case DotNetPropertyType.Binary:
                    {
                        IDummyType arrayObjectType = dummyType.GetElementType();

                        root = new XmlNode(arrayObjectType.Name);

                        byte[] binaryValue = value as byte[];

                        root.Text = Pixysoft.Security.UrlCoder.UrlEncode(binaryValue);

                        if (string.IsNullOrEmpty(root.Text))
                            return null;

                        return root;
                    }


                case DotNetPropertyType.Object:
                case DotNetPropertyType.Interface:
                    {
                        return SerializeObject(value, objectType, dummyType);
                    }

                case DotNetPropertyType.Enum:
                case DotNetPropertyType.Value:
                    {
                        root = new XmlNode(objectType.Name);

                        root.Text = GetStringValueByType(dummyType.DataType, value);

                        if (string.IsNullOrEmpty(root.Text))
                            return null;

                        return root;
                    }

                case DotNetPropertyType.Unknown:
                default:
                    throw new Exception("unknown object type.");
            }
        }
        /// <summary>
        /// 对结构体进行序列化
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static XmlNode SerializeObject(object value, Type objectType, IDummyType dummyType)
        {
            if (value == null)
                return null;

            XmlNode root = new XmlNode(GetRootName(dummyType));

            IBeanMap objectBean = ReflectionManager.CreateBeanMap(value);

            DynamicInterfacePropertyCollection iPropertyCollection = new DynamicInterfacePropertyCollection(dummyType.GetInterfaces());

            foreach (IDummyPropertyInfo propertyinfo in dummyType.GetProperties())//默认输入都是类 不会是接口
            {
                DynamicPropertyStructure property = new DynamicPropertyStructure();

                property.InitializeProperty(iPropertyCollection, propertyinfo);

                if (property.IsIgnore)
                    continue;

                if (property.IsAttribute)
                {
                    SetPropertyValueByPropertyAttribute(objectBean, root, property);
                }
                else
                {
                    SetPropertyValue(objectBean, root, property);
                }
            }

            return root;
        }
        /// <summary>
        /// 结合接口的信息序列化对象
        /// </summary>
        /// <param name="root"></param>
        /// <param name="property"></param>
        /// <param name="property"></param>
        private static void SetPropertyValue(IBeanMap objectBean, XmlNode root, DynamicPropertyStructure property)
        {
            switch (property.PropertyType.PropertyType)
            {
                case DotNetPropertyType.Object:
                case DotNetPropertyType.Interface:
                    {
                        // 1,864ms:1625ms
                        XmlNode childNode = Serialize(objectBean.GetValue(property.PropertyInfo.Name));

                        if (childNode == null)
                            return;

                        childNode.ElementName = property.PropertyName;

                        root.Nodes.Add(childNode);

                        break;
                    }
                case DotNetPropertyType.Enum:
                case DotNetPropertyType.Value:
                case DotNetPropertyType.Binary:
                    {
                        // 1,864ms:1,434ms

                        XmlNode childNode = Serialize(objectBean.GetValue(property.PropertyInfo.Name));

                        if (childNode == null)
                            return;

                        childNode.ElementName = property.PropertyName;

                        root.Nodes.Add(childNode);

                        break;


                        ////NO RECURSIVE 1,790ms

                        //object childValue = objectBean.GetValue(property.PropertyInfo.Name);

                        //if (childValue == null)
                        //    return;

                        //Type childType = childValue.GetType();

                        //XmlNode childNode = new XmlNode(childType.Name);

                        //childNode.Text = GetStringValueByType(Pixysoft.Tools.ParserHelper.GetDataTypeByType(childType), childValue);

                        //if (string.IsNullOrEmpty(childNode.Text))
                        //    return;

                        //childNode.ElementName = property.PropertyName;

                        //root.Nodes.Add(childNode);

                        //break;
                    }

                case DotNetPropertyType.EnumList:
                case DotNetPropertyType.EnumArray:
                case DotNetPropertyType.ValueList:
                case DotNetPropertyType.ValueArray:
                case DotNetPropertyType.ObjectList:
                case DotNetPropertyType.ObjectArray:
                case DotNetPropertyType.InterfaceList:
                case DotNetPropertyType.InterfaceArray:
                case DotNetPropertyType.BinaryList:
                    {
                        // 606ms

                        //由于使用了递归，直接改变了xml传输的格式。导致出错。旧版本无法解析

                        XmlNode childNode = Serialize(objectBean.GetValue(property.PropertyInfo.Name));

                        //1,692ms 1,754ms

                        if (childNode == null)
                            return;

                        childNode.ElementName = string.Format(default_format_element_arrayof, property.PropertyName);

                        //10-04-17 为了兼容旧版本 

                        foreach (XmlNode subChildNode in childNode.Nodes)
                        {
                            subChildNode.ElementName = property.PropertyName;
                        }

                        root.Nodes.Add(childNode);

                        // 1,906ms

                        break;
                    }

                case DotNetPropertyType.Unknown:
                default:
                    {
                        //目前不支持集合里面是集合，例如List<byte[]>

                        break;
                    }
            }
        }
        /// <summary>
        /// 根据接口定义设置值
        /// </summary>
        /// <param name="root"></param>
        /// <param name="property"></param>
        /// <param name="property"></param>
        private static void SetPropertyValueByPropertyAttribute(IBeanMap objectBean, IXmlNode root, DynamicPropertyStructure property)
        {
            switch (property.PropertyType.PropertyType)
            {
                case DotNetPropertyType.Enum:
                case DotNetPropertyType.Value:
                    {
                        string stringvalue = GetStringValueByType(property.PropertyType.DataType, objectBean.GetValue(property.PropertyInfo.Name));

                        if (string.IsNullOrEmpty(stringvalue))
                            break;

                        root.Properties.Add(property.PropertyName, stringvalue);

                        break;
                    }
                case DotNetPropertyType.Object:
                case DotNetPropertyType.Interface:
                case DotNetPropertyType.Binary:
                case DotNetPropertyType.EnumArray:
                case DotNetPropertyType.ValueArray:
                case DotNetPropertyType.ObjectArray:
                case DotNetPropertyType.InterfaceArray:
                case DotNetPropertyType.BinaryList:
                case DotNetPropertyType.EnumList:
                case DotNetPropertyType.ValueList:
                case DotNetPropertyType.ObjectList:
                case DotNetPropertyType.InterfaceList:
                case DotNetPropertyType.Unknown:
                default:
                    {
                        throw new Exception(
                            string.Format("xml property mark do not support non-value type. propertyname={0}",
                            property.PropertyName));
                    }
            }
        }
    }

    /// <summary>
    /// 复用方法
    /// </summary>
    static partial class DynamicReflectionController
    {
        private const string default_format_element_arrayof = "ArrayOf{0}";

        /// <summary>
        /// 获取xmlRoot节点属性
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private static string GetRootName(IDummyType type)
        {
            foreach (object attributeValue in type.GetCustomAttributes())
            {
                if (!(attributeValue is XmlRootAttribute))
                    continue;

                XmlRootAttribute rootValue = attributeValue as XmlRootAttribute;

                if (string.IsNullOrEmpty(rootValue.ElementName))
                    return type.Name;

                return rootValue.ElementName.Trim();
            }

            foreach (IDummyType interfaceType in type.GetInterfaces())
            {
                foreach (object attributeValue in interfaceType.GetCustomAttributes())
                {
                    if (!(attributeValue is XmlRootAttribute))
                        continue;

                    XmlRootAttribute rootValue = attributeValue as XmlRootAttribute;

                    if (string.IsNullOrEmpty(rootValue.ElementName))
                        return type.Name;

                    return rootValue.ElementName.Trim();
                }
            }

            return type.Name;
        }

        /// <summary>
        /// 返回当期接口和继承的接口的所有property
        /// </summary>
        /// <param name="dummyType"></param>
        /// <returns></returns>
        private static IDummyPropertyInfo[] CombineWithInterfaceProperties(IDummyType dummyType)
        {
            if (dummyType.PropertyType != DotNetPropertyType.Interface)
                throw new VerificationFailedException("only support interface type.");

            List<IDummyPropertyInfo> list = new List<IDummyPropertyInfo>();

            foreach (IDummyPropertyInfo info in dummyType.GetProperties())
            {
                list.Add(info);
            }

            foreach (IDummyType itype in dummyType.GetInterfaces())
            {
                list.AddRange(CombineWithInterfaceProperties(itype));
            }

            return list.ToArray();
        }

        /// <summary>
        /// 包括继承关系 搜索接口的属性
        /// </summary>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        private static PropertyInfo GetPropertyCombineWithInterface(Type type, string name)
        {
            PropertyInfo info = type.GetProperty(name);

            if (info != null)
                return info;

            foreach (Type itype in type.GetInterfaces())
            {
                info = GetPropertyCombineWithInterface(itype, name);

                if (info != null)
                    return info;
            }

            return null;
        }

        /// <summary>
        /// 根据类型返回结果 特别针对值类型
        /// </summary>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string GetStringValueByType(DotNetDataType type, object value)
        {
            //1,441ms  

            //1,922ms 1,867ms

            if (value == null)
                return null;

            switch (type)
            {
                case DotNetDataType.Char:
                    {
                        char tvalue = (char)value;

                        if (tvalue == Char.MinValue || tvalue == Char.MaxValue)
                            return null;

                        return value.ToString();
                    }
                case DotNetDataType.Decimal:
                    {
                        Decimal tvalue = (Decimal)value;

                        if (tvalue == Decimal.MinValue || tvalue == Decimal.MaxValue)
                            return null;

                        return tvalue.ToString();
                    }
                case DotNetDataType.Double:
                    {
                        Double tvalue = (Double)value;

                        if (tvalue == Double.MinValue || tvalue == Double.MaxValue)
                            return null;

                        return tvalue.ToString();
                    }
                case DotNetDataType.Int32:
                    {
                        Int32 tvalue = (Int32)value;

                        if (tvalue == Int32.MinValue || tvalue == Int32.MaxValue)
                            return null;

                        return tvalue.ToString();
                    }
                case DotNetDataType.Int64:
                    {
                        Int64 tvalue = (Int64)value;

                        if (tvalue == Int64.MinValue || tvalue == Int64.MaxValue)
                            return null;

                        return tvalue.ToString();
                    }
                case DotNetDataType.Single:
                    {
                        Single tvalue = (Single)value;

                        if (tvalue == Single.MinValue || tvalue == Single.MaxValue)
                            return null;

                        return tvalue.ToString();
                    }
                case DotNetDataType.Byte:
                    {
                        Byte tvalue = (Byte)value;

                        if (tvalue == Byte.MinValue || tvalue == Single.MaxValue)
                            return null;

                        return value.ToString();
                    }
                case DotNetDataType.Boolean:
                    {
                        return value.ToString();
                    }
                case DotNetDataType.DateTime:
                case DotNetDataType.Object:
                case DotNetDataType.String:
                case DotNetDataType.UNKNOWN:
                default:
                    return value.ToString().Trim();
            }
        }

        /// <summary>
        /// 是当前类继承的接口的所有属性的集合
        /// 如果接口有attribute的描述，则使用接口的attribute
        /// 否则 就使用类的
        /// </summary>       
        class DynamicInterfacePropertyCollection
        {
            Dictionary<string, IDummyPropertyInfo> propertylist = new Dictionary<string, IDummyPropertyInfo>();

            public DynamicInterfacePropertyCollection(IDummyType[] interfacetypes)
            {
                foreach (IDummyType interfacetype in interfacetypes)
                {
                    foreach (IDummyPropertyInfo property in interfacetype.GetProperties())
                    {
                        if (propertylist.ContainsKey(property.Name))
                            continue;

                        propertylist.Add(property.Name, property);
                    }
                }
            }

            public bool ContainProperty(string name)
            {
                return propertylist.ContainsKey(name);
            }

            public IDummyPropertyInfo GetProperty(string name)
            {
                if (!ContainProperty(name))
                    return null;

                return propertylist[name];
            }
        }

        /// <summary>
        /// 接口的结构描述 兼顾了类和接口关于property的描述
        /// </summary>
        class DynamicPropertyStructure
        {
            //base info

            PropertyInfo reflectPropertyInfo;//反射的property对象

            IDummyPropertyInfo propertyInfo;//propertyinfo对象

            string propertyName;//如果有attribute，则使用attribute，否则使用类的声明


            // manual info

            bool isAttribute;//是否被序列化为attribute

            bool isIgnore;//是否可以忽略

            public DynamicPropertyStructure()
            {
                //serialize使用
            }

            public DynamicPropertyStructure(PropertyInfo info)
            {
                this.reflectPropertyInfo = info;
            }


            public void InitializeProperty(DynamicInterfacePropertyCollection iCollection, IDummyPropertyInfo info)
            {
                this.propertyInfo = info;

                //首先尝试获取接口关于property的描述

                IDummyPropertyInfo iPropertyInfo = iCollection.GetProperty(info.Name);


                //element attribute

                System.Xml.Serialization.XmlElementAttribute elementAttribute = info.GetCustomAttribute(typeof(System.Xml.Serialization.XmlElementAttribute)) as System.Xml.Serialization.XmlElementAttribute;

                if (elementAttribute == null && iPropertyInfo != null)
                {
                    elementAttribute = iPropertyInfo.GetCustomAttribute(typeof(System.Xml.Serialization.XmlElementAttribute)) as System.Xml.Serialization.XmlElementAttribute;
                }
                if (elementAttribute == null)
                {
                    propertyName = info.Name;
                }
                else if (string.IsNullOrEmpty(elementAttribute.ElementName))
                {
                    propertyName = info.Name;
                }
                else
                {
                    propertyName = elementAttribute.ElementName.Trim();
                }


                // property mapping

                System.Xml.Serialization.XmlAttributeAttribute attributeattribute = info.GetCustomAttribute(typeof(System.Xml.Serialization.XmlAttributeAttribute))
                    as System.Xml.Serialization.XmlAttributeAttribute;

                if (attributeattribute == null && iPropertyInfo != null)
                {
                    attributeattribute = iPropertyInfo.GetCustomAttribute(typeof(System.Xml.Serialization.XmlAttributeAttribute))
                        as System.Xml.Serialization.XmlAttributeAttribute;
                }
                if (attributeattribute == null)
                {
                    isAttribute = false;
                }
                else
                {
                    isAttribute = true;

                    propertyName = attributeattribute.AttributeName;
                }


                //ignore mapping

                System.Xml.Serialization.XmlIgnoreAttribute ignore = info.GetCustomAttribute(typeof(XmlIgnoreAttribute)) as System.Xml.Serialization.XmlIgnoreAttribute;

                if (ignore == null && iPropertyInfo != null)
                {
                    ignore = iPropertyInfo.GetCustomAttribute(typeof(System.Xml.Serialization.XmlIgnoreAttribute)) as System.Xml.Serialization.XmlIgnoreAttribute;
                }
                if (ignore != null)
                    this.isIgnore = true;
                else
                    this.isIgnore = false;
            }



            public PropertyInfo ReflectPropertyInfo
            {
                get
                {
                    return this.reflectPropertyInfo;
                }
            }

            public IDummyPropertyInfo PropertyInfo
            {
                get
                {
                    return propertyInfo;
                }
            }

            public IDummyType PropertyType
            {
                get { return propertyInfo.PropertyType; }
            }

            public string PropertyName
            {
                get { return propertyName; }
            }

            public bool IsIgnore
            {
                get { return isIgnore; }
            }

            public bool IsAttribute
            {
                get { return isAttribute; }
            }
        }
    }

}
